﻿@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/Layout.cshtml";
}

<div class="fr" onclick="switchMode();" style="cursor: pointer;"><b>Mode:</b> <span id="mode"></span></div>

<h1>Config Manipulation Language (CML)</h1>

<table style="width: 100%;padding: 0;vertical-align: top;" cellspacing="10px">
	<tr>
		<td style="vertical-align: top;">
			<h2>CML Script</h2>
			<textarea id="input" style="width:100%; height: 600px;" placeholder="Enter CML script here!">@Model.Sample</textarea>
			<div class="action-set">				
				<input type="button" value="Parse" onclick="buildAndParse();" class="parse-mode" />
				<input type="button" value="Run Script" onclick="runScript();" class="run-mode"/>
			</div>
		</td>
		<td style="vertical-align: top;" class="parse-mode">
			<h2>PEG JS Grammer</h2>
			<textarea id="grammar" style="width:100%; height: 600px;">@Model.Grammer</textarea>
		</td>
	</tr>
</table>

<div class="run-mode">
	<table>
		<tr>
			<td>Source folder:</td>
			<td>
				<input id="source-folder" value="c:\CodePlex\peg\CML\CML.TestConfigs\Source" class="wide" />
			</td>
		</tr>
		<tr>
			<td>Ouptut folder:</td>
			<td>
				<input id="target-folder" value="c:\CodePlex\peg\CML\CML.TestConfigs\Output" class="wide" />
			</td>
		</tr>
		<tr>
			<td>Write Target:</td>
			<td>
				<input id="write-target" type="checkbox" />
			</td>
		</tr>
		<tr>
			<td>Script File Name:</td>
			<td>
				<input id="download-filename" value="script.cml" /> <input type="button" value="Download" onclick="downloadScript();" class="" />
			</td>
		</tr>
	</table>
</div>


<div class="parse-mode">
	<h2>Generating Parser Result</h2>
	<div id="build-message"></div>
</div>

<h2>Script Parsing Result</h2>
<div id="parse-message"></div>

<div class="parse-mode">
	<h2>Parse Output</h2>
	<pre id="output">Output not available</pre>
</div>

<div class="run-mode">
	<h2>Run Script Output</h2>
	<div id="run-output">Output not available</div>
</div>

<script type="text/javascript">
	var parser;

	function build() {
		$('#build-message').attr("class", "message progress").text("Building the parser...");
		var result = false;
		try {
			var timeBefore = (new Date).getTime();
			var g = $("#grammar").val();
			var parserSource = PEG.buildParser(g, {
				cache: false,
				optimize: 'speed',
				output: "source"
			});
			var timeAfter = (new Date).getTime();

			parser = eval(parserSource);

			$("#build-message")
							.attr("class", "message info")
							.html("Parser built successfully.");
			result = true;
		} catch (e) {
			$("#build-message").attr("class", "message error").text(buildErrorMessage(e));
			result = false;
		}
		return result;
	}

	function parse() {
		$("#input").removeAttr("disabled");
		$("#parse-message").attr("class", "message progress").text("Parsing the input...");
		$("#output").addClass("disabled").text("Output not available.");

		try {
			var output = parser.parse(getScript());
			$("#parse-message").attr("class", "message info").text("Input parsed successfully.");        
			$("#output").removeClass("disabled").text(jsDump.parse(output));
			var result = true;
		} catch (e) {
			$("#parse-message").attr("class", "message error").text(buildErrorMessage(e));

			var result = false;
		}

		return result;
	}

	function buildAndParse() {
		$("#parse-message").html();

		var r = build();
		if (r)
			return parse();
	}

	function buildErrorMessage(e) {
		return e.line !== undefined && e.column !== undefined
					  ? "Line " + e.line + ", column " + e.column + ": " + e.message
					  : e.message;
	}

	function runScript() {
		var r = buildAndParse();
		if (!r)
			return;
		$.ajax({
			type: 'POST',
			url: "/demo/runscript",
			dataType: 'json',
			contentType: 'application/json; charset=utf-8',
			data: JSON.stringify({
				cml: getScript(),
				sourceFolder: $("#source-folder").val(),
				targetFolder: $("#target-folder").val(),
				writeTarget: $("#write-target").prop("checked") 

			}),
			success: function (data) {
				if (data.success) {
					renderRunOutput(data.result);
				}
				else {
					$('#run-output').attr("class", "message error").html('Failed to Run Script! ' + data.message);
				}
			}
		});
	}

	var templateHelpers = {
		renderIframe: function () {
			var html = '';
			if(this.Action == 'edit')
			{
				var args   = {
					source: vkbeautify.xml(this.OldContent || ''),
					diff  : vkbeautify.xml(this.NewContent || ''),
					lang  : "xml",
				};
				this.output = prettydiff(args);
				html = '<iframe id="'+this.Id+'" frameborder="0" class="diff" onLoad="resizeIFrame(this);"></iframe>';
			}
			if(this.Action == 'add')
			{
				this.output = vkbeautify.xml(this.NewContent || '');
				html = '<pre id="'+this.Id+'" class="xml">' + + '</pre>';
			}
			return html;
		},
		renderDiff: function(){
			if(this.Action == 'edit')
			{
				var iframe = document.getElementById(this.Id);
				if(iframe==null)
					return;
				iframe.contentWindow.document.open('text/htmlreplace');
				iframe.contentWindow.document.write(this.output);
				iframe.contentWindow.document.close();
			}
			if(this.Action == 'add')
			{
				$('#'+this.Id).text(this.output);
			}
		}
	}

	function resizeIFrame(iframe)
	{
		var $doc = $(iframe.contentWindow.document);
		$doc.find('div.doc:first').remove();
		$doc.find('h1:first').remove();
		$doc.find('p:first').remove();
        var newheight=iframe.contentWindow.document .body.scrollHeight;
        var newwidth=iframe.contentWindow.document .body.scrollWidth;
		iframe.height= (newheight+30) + "px";
		//iframe.width= (newwidth+30) + "px";
	}

	function renderRunOutput(l) {

		var template = _.template($("#result-template").html());
		for (var i = 0; i < l.length; i++) {
			_.extend(l[i], templateHelpers);			
		}
		var html = template(l);
		$('#run-output').attr("class", "").html(html);
		for (var i = 0; i < l.length; i++) {
			l[i].renderDiff();			
		}
	}

	function switchMode(currentMode) {
		if (!currentMode)
			currentMode = $('#mode').html();
		if (currentMode == 'parse') {
			$('#mode').html('run'); 
			$('.parse-mode').hide();
			$('.run-mode').show();
		}
		else {
			$('#mode').html('parse');
			$('.parse-mode').show();
			$('.run-mode').hide();
		}
	}

	function downloadScript()
	{
		var fn = $('#download-filename').val();
		if(!fn)
			fn = 'script.cml';

		var url = 'data:application/stream;script.cml;charset=utf-8,' + encodeURIComponent(getScript());
		//window.open(url);

		function eventFire(el, etype){
			if (el.fireEvent) {
				(el.fireEvent('on' + etype));
			} else {
				var evObj = document.createEvent('Events');
				evObj.initEvent(etype, true, false);
				el.dispatchEvent(evObj);
			}
		}

		var link = document.createElement("a");
		link.download = fn;
		link.href = url;
		eventFire(link, "click");
	}

	function getScript()
	{
		//$("#input").val()
		return editAreaLoader.getValue('input');
	}

	$(function () {
		switchMode('parse');
		buildAndParse();

		editAreaLoader.init({
			id : "input"			// textarea id
			,syntax: "cml"			// syntax to be uses for highgliting
			,start_highlight: true		// to display with highlight mode on start-up
		});
	});
</script>


<script type="text/template" id="result-template">
    <% _.each( data, function( r ){ %> 
        <% if ( r.ErrorCode ){ %>
            <div class="message error"><%=r.Path %>
				<div class="indent"><%=r.ErrorDescription %></div>				
			</div>
        <% } else { %>
            <div class="message info"><%=r.Path %> - <%=r.Action %>
				<div class="indent"><%=r.renderIframe() %></div>
			</div>
        <% } %> 
    <% }); %>
</script>

